﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using MMSWebsite.Models;

namespace MMSWebsite.DataAccessManagement
{
    public class GroupAccessProvider
    {
        EmployeeAccessProvider _eap = new EmployeeAccessProvider(); 
        MMSEntities _entities = new MMSEntities();

        public List<Group> GetAllGroups()
        {
            var groups = new List<Group>();
            var mmsgroups = _entities.MMS_GROUPs.OrderBy(x=>x.GroupName).ToList();
            foreach (var mmsGroup in mmsgroups)
            {
                groups.Add(ConvertMMSGroupToGroup(mmsGroup));
            }
            return groups;
        }

        public Group GetGroupById(int id)
        {
            return ConvertMMSGroupToGroup(_entities.MMS_GROUPs.FirstOrDefault(g => g.Id == id));
        }

        public int GetGroupIdByName(string groupname)
        {
            return _entities.MMS_GROUPs.Where(g=>g.GroupName==groupname).Select(g=>g.Id).FirstOrDefault();
        }

        public List<string> GetAllGroupName()
        {
            return _entities.MMS_GROUPs.Select(g => g.GroupName).ToList();
        }

        public void AddGroup(Group group)
        {
            _entities.AddToMMS_GROUPs(ConvertGroupToMMSGroup(group));
            _entities.SaveChanges();
            var idGroup = GetGroupIdByName(group.GroupName);
            SetAreaForGroup(idGroup, group.Area.City, group.Area.Districts);
        }

        public void RemoveGroup(int id)
        {
            _entities.MMS_GROUPs.DeleteObject(_entities.MMS_GROUPs.Single(g => g.Id == id));
            _entities.SaveChanges();
        }

        public void UpdateGroup(Group group)
        {
            var updategroup = _entities.MMS_GROUPs.Single(g => g.Id == group.Id);
            updategroup.GroupName = group.GroupName;
            updategroup.Description = group.Description;
            updategroup.Responsibility = group.Responsibility != null ? group.Responsibility.Employee.Id : (int?) null;
            SetAreaForGroup(group.Id, group.Area.City, group.Area.Districts);
            _entities.SaveChanges();
        }

        public bool CheckGroupExist(string groupname, bool editView)
        {
            var groups = GetAllGroups();
            if (editView)
            {
                var removegroup = groups.FirstOrDefault(g => g.GroupName == groupname);
                if (removegroup != null) groups.Remove(groups.FirstOrDefault(g => g.GroupName == groupname));
            }
            return groups.Any(@group => @group.GroupName == groupname);
        }

        public void SetAreaForGroup(int groupId, string city, List<string> districts)
        {
            //var currentCity =
            //    _entities.MMS_AREAs.Where(x => x.GroupId == groupId).Select(x => x.CityName).Distinct().FirstOrDefault();
            //if(currentCity != city)
            //{
            var oldareas = _entities.MMS_AREAs.Where(x => x.GroupId == groupId);
            foreach (var oldarea in oldareas)
            {
                oldarea.GroupId = null;
            }
            //}
            _entities.SaveChanges();
            var areas = _entities.MMS_AREAs.Where(d => d.CityName == city).Distinct();
            //_entities.SaveChanges();
            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
            {
                try
                {
                    //foreach (var area in areas)
                    //{
                    //    foreach (var district in districts)
                    //    {
                    //        if (area.DistrictName == district)
                    //        { area.GroupId = groupId; break; }
                    //    }
                    //}
                    foreach (var district in districts)
                    {
                        foreach (var area in areas)
                        {
                            if(area.DistrictName == district)
                            { area.GroupId = groupId; break; }
                        }
                    }
                    _entities.SaveChanges();
                    ts.Complete();
                }
                catch (Exception)
                {
                }
            }
        }

        private Group ConvertMMSGroupToGroup(MMS_GROUP mmsGroup)
        {


            //get Responsible Emp
            var responsibility = new EmployeeViewModel();
            
            if(mmsGroup.Responsibility != null)
                responsibility = _eap.GetEmployeeById(mmsGroup.MMS_EMPLOYEE.Id);
            else responsibility = null;
            return new Group
                            {
                                Id = mmsGroup.Id, GroupName = mmsGroup.GroupName,
                                Description = mmsGroup.Description, Responsibility = responsibility,
                                Area = GetGroupAreaById(mmsGroup.Id)
                            };

        }

        public GroupArea GetGroupAreaById(int id)
        {
            var mmsGroup = _entities.MMS_GROUPs.FirstOrDefault(x => x.Id == id);
            return new GroupArea //get Area of Group
                       {
                           City = mmsGroup.MMS_AREA.Select(x=>x.CityName).FirstOrDefault(),
                           Districts = mmsGroup.MMS_AREA.Select(x => x.DistrictName).ToList()
                       };
        }

        private MMS_GROUP ConvertGroupToMMSGroup(Group group)
        {
            var mssgroup = new MMS_GROUP();
            mssgroup.GroupName = group.GroupName;
            mssgroup.Description = group.Description;
            mssgroup.Responsibility = group.Responsibility != null ? group.Responsibility.Employee.Id : (int?) null;
            return mssgroup;
        }
    }
}